package cn.com.pc.content.config;

import cn.com.pc.aaa.AaaClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.WebClient;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

import static cn.com.pc.aaa.Constants.*;

/**
 * AAA 安全配置
 */
@Slf4j
@Configuration
public class AAAConfig {

    @Value("${aaa.uri}")
    String appKey;
    @Value("${aaa.appSecret:}")
    String appSecret;
    @Value("${aaa.idpServer:}")
    String idpServer;
    @Value("${aaa.gatewayServer:}")
    String gatewayServer;

    @Bean
    AaaClient aaaClient() {
        AaaClient client = new AaaClient();
        client.setIdpServer(idpServer);
        client.setGatewayServer(gatewayServer);
        client.setAppSecret(appSecret);
        client.setAppKey(appKey);

        client.init();

        return client;
    }

    @Bean
    @LoadBalanced
    @Qualifier("WCB_L")
    WebClient.Builder builderInner() {
        return WebClient.builder();
    }

    @Bean
    @Qualifier("WCB_G")
    WebClient.Builder builderOuter() {
        return WebClient.builder();
    }

    @Bean
    @Qualifier("WC_LT0")
    WebClient webClient0(@Qualifier("WCB_L") WebClient.Builder builder, AaaClient aaaClient) {
        // add x-local-token, x-app, x-biz, x-site header

        log.info("+++ Web client LT0 created with aaaClient: " + aaaClient);
        return builder
                .filter((clientRequest, nextFilter) -> {
                    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
                            .header(X_LOCAL_TOKEN, aaaClient.getLocalToken())   // 依赖 idpServer 和 gatewayServer
                            .header(X_SITE, aaaClient.getFrom().getSite())
                            .header(X_BIZ, aaaClient.getFrom().getBiz())
                            .header(X_APP, aaaClient.getFrom().getApp())
                            .build();
                    return nextFilter.exchange(filteredRequest);
                })
                .build();
    }

    @Bean
    @Qualifier("WC_LT")
    WebClient webClient(@Qualifier("WCB_L") WebClient.Builder builder) {
        log.info("+++ Web client GT created");
        return builder
                .filter((clientRequest, nextFilter) -> {
                    HttpServletRequest req = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
                            .header(X_LOCAL_TOKEN, req.getHeader(X_LOCAL_TOKEN))    // 依赖 idpServer
                            .header(X_SITE, req.getHeader(X_SITE))
                            .header(X_BIZ, req.getHeader(X_BIZ))
                            .header(X_APP, req.getHeader(X_APP))
                            .build();
                    return nextFilter.exchange(filteredRequest);
                })
                .build();
    }

    @Bean
    @Qualifier("WC_GT")
    WebClient webClientGlobalToken(@Qualifier("WCB_G") WebClient.Builder builder, AaaClient aaaClient) {
        // add x-token, x-app, x-biz, x-site header
        log.info("+++ Web client GT created with aaaClient: " + aaaClient);
        return builder
                .filter((clientRequest, nextFilter) -> {
                    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
                            .header(X_TOKEN, aaaClient.getGlobalToken())    // 依赖 idpServer
                            .header(X_SITE, aaaClient.getFrom().getSite())
                            .header(X_BIZ, aaaClient.getFrom().getBiz())
                            .header(X_APP, aaaClient.getFrom().getApp())
                            .build();
                    return nextFilter.exchange(filteredRequest);
                })
                .build();
    }

}
